package cn.com.se.网络.nio;

import com.sun.xml.internal.messaging.saaj.util.ByteOutputStream;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author hu.rl
 * NIO server端
 */
public class ServerTest {
    public static void main(String[] args) throws Exception {
        server();
    }

    public static void server() {
        ServerSocketChannel channel = null;
        try {
            // 创建selector
            Selector selector = Selector.open();
            // 根据selector创建通道
            channel = ServerSocketChannel.open();
            channel.configureBlocking(false);
            channel.socket().setReuseAddress(true);
            channel.bind(new InetSocketAddress(8020));
            channel.register(selector, SelectionKey.OP_ACCEPT, new Integer(1));

            while (true) {
                if (selector.select() > 0) {
                    // 检测有关注的操作已经就绪的key
                    Set<SelectionKey> sets = selector.selectedKeys();
                    Iterator<SelectionKey> keys = sets.iterator();
                    while (keys.hasNext()) {
                        SelectionKey key = keys.next();
                        keys.remove();
                        // 处理 accept 事件
                        if (key.isAcceptable()) {
                            key.attach(new Integer(1));
                            SocketChannel schannel = ((ServerSocketChannel) key.channel()).accept();
                            schannel.configureBlocking(false);
                            schannel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
                        }
                        // 处理 read 事件
                        if (key.isReadable()) {
                            SocketChannel schannel = (SocketChannel) key.channel();
                            ByteBuffer buf = ByteBuffer.allocate(1024);
                            ByteOutputStream output = new ByteOutputStream();
                            int len = 0;
                            while ((len = schannel.read(buf)) != 0) {
                                buf.flip();
                                byte by[] = new byte[buf.remaining()];
                                buf.get(by);
                                output.write(by);
                                buf.clear();
                            }
                            String str = new String(output.getBytes());
                            key.attach(str);
                        }
                        // 处理 write 事件
                        if (key.isWritable()) {
                            Object object = key.attachment();
                            String attach = object != null ? "server replay: " + object.toString() : "server replay: ";
                            System.out.println(attach);
                            SocketChannel schannel = (SocketChannel) key.channel();
                            schannel.write(ByteBuffer.wrap(attach.getBytes()));
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (channel != null) {
                try {
                    channel.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}
